package com.itheima.aop;

import com.itheima.annotion.WebLog;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.lang.model.element.VariableElement;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * @作者 itcast
 * @创建日期 2020/10/13 20:46
 **/
@Aspect
@Component
public class LogAspect {
    @Pointcut("@annotation(com.itheima.annotion.WebLog)")
    public  void controllerAspect() {
    }

    @Around("controllerAspect()")
    public Object around(ProceedingJoinPoint joinPoint){
        Object result;
        try {
            // 方法签名 能够获得方法对象
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            // 根据请求上下文获取请求对象
            RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
            // 通过方法反射调用标注的 @WebLog
            WebLog webLog = method.getAnnotation(WebLog.class);
            long startTime = System.currentTimeMillis();
            // 方法调用
            result = joinPoint.proceed();
            long endTime = System.currentTimeMillis();
            System.out.println("==============web 日志 start=================");
            System.out.println(" 请求方式及Uri ==>"+request.getMethod() + " " + request.getRequestURI() );
            System.out.println(" 方法持续时间==>"+(endTime - startTime));
            System.out.println(" 方法的类名 ==>"+method.getDeclaringClass().getName());
            System.out.println(" 方法的名称 ==>"+method.getName());
            System.out.println(" 用户操作 ==>"+webLog.value());
            System.out.println(" 请求用户IP ==>"+request.getRemoteHost());
            System.out.println("==============web 日志 end=================");
            return result;
        } catch (Throwable throwable) {
            throw new RuntimeException("方法调用出现异常");
        }
    }
}
